---
title: Vue + Hanko
sidebar_label: Vue
keywords: [vue]
sidebar_custom_props:
  docCardIconName: vue
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Vue

In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your Vue application.
## Install dependencies

Install the `@teamhanko/hanko-elements` package:

```shell npm2yarn
npm install @teamhanko/hanko-elements
```

## Configure component resolution

Vue needs to know which elements to treat as custom elements, otherwise it will issue a warning regarding component
resolution. To do so, provide a predicate function that determines which elements are to be considered custom elements
to [`compilerOptions.isCustomElement`](https://vuejs.org/guide/extras/web-components.html#using-custom-elements-in-vue)
in your configuration:

```mdx-code-block
<Tabs>
<TabItem value="vite" label="Vite Config">
```

```js {7-9} title="vite.config.js" showLineNumbers
import vue from '@vitejs/plugin-vue'

export default {
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag.startsWith("hanko-")
        }
      }
    })
  ]
}
```

```mdx-code-block
</TabItem>
<TabItem value="cli" label="Vue CLI Config">
```

```js {8-10} title="vue.config.js" showLineNumbers
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => ({
        ...options,
        compilerOptions: {
          isCustomElement: (tag) => tag.startsWith("hanko-")
        }
      }))
  }
}
```

```mdx-code-block
</TabItem>
</Tabs>
```

## Add `<hanko-auth>` component

To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the
`register` function from `@teamhanko/hanko-elements` in your Vue component. Call it with the URL of the Hanko API as an argument
to register the `<hanko-auth>` element with
the browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then
use the element in your component template.

:::info

If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.

:::

```js title="HankoAuth.vue" showLineNumbers
<script setup>
import { onMounted } from "vue";
import { register } from "@teamhanko/hanko-elements";

const hankoApi = "<YOUR_API_URL>";

onMounted(() => {
  // register the component
  // see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
  register(hankoApi)
    .catch((error) => {
      // handle error
    });
});
</script>

<template>
  <hanko-auth />
</template>
```

## Add `<hanko-events>` component

The `<hanko-events>` component provides a convenient way to subscribe to specific
[events](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#events) without displaying any UI elements.
The other hanko-elements will also dispatch these events.

To utilize this functionality in your Vue application, you can leverage Vue's event binding mechanism and define
callback functions within your component. This allows you to respond to the dispatched events accordingly.

Import the `register` function from `@teamhanko/hanko-elements` in your Vue component. Call it with the URL of the
Hanko API as an argument to register the `<hanko-events>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry).
Then use the element in your component template.

```js title="HankoAuth.vue" showLineNumbers
<script setup>
// highlight-next-line
import { useRouter } from "vue-router";
import { onMounted } from "vue";
import { register } from "@teamhanko/hanko-elements";

const hankoApi = "<YOUR_API_URL>";

// highlight-next-line
const router = useRouter();

// highlight-start
const redirectAfterLogin = () => {
  // successfully logged in, redirect to a page in your application
  router.push({ path: "..." });
};
// highlight-end

onMounted(() => {
  // register the component
  // see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
  register(hankoApi))
    .catch((error) => {
      // handle error
    });
});
</script>

<template>
  // highlight-next-line
  <hanko-events @onAuthFlowCompleted="redirectAfterLogin" />
  <hanko-auth />
</template>
```

Alternatively, subscribe directly on the `<hanko-auth>` element:

```js showLineNumbers
<hanko-auth @onAuthFlowCompleted="redirectAfterLogin" />
```

## Add `<hanko-profile>` component {#hanko-profile}

To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your Vue component. Call it with the
URL of the Hanko API as an argument to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then use
the element in your component.

```js title="HankoProfile.vue" showLineNumbers
<script setup>
import { onMounted } from "vue";
import { register } from "@teamhanko/hanko-elements";

const hankoApi = "<YOUR_API_URL>";

onMounted(() => {
  // register the component
  // see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
  register(hankoApi)
    .catch((error) => {
      // handle error
    });
});
</script>

<template>
  <hanko-profile />
</template>

```

## Implement logout

Use the Hanko client provided by `@teamhanko/hanko-elements` to log out users. On logout a custom event is
dispatched that you can subscribe to:

```js title="HankoProfile.vue" showLineNumbers
<script setup>
import { onMounted } from "vue";
// highlight-start
import { useRouter } from "vue-router";
import { register, Hanko } from "@teamhanko/hanko-elements";
// highlight-end

const hankoApi = "<YOUR_API_URL>";

// highlight-start
const router = useRouter();
const hanko = new Hanko(hankoApi);
// highlight-end

// highlight-start
const logout = () => {
  hanko.user.logout().catch((error) => {
    // handle error
  })
}
// highlight-end

// highlight-start
const redirectAfterLogout = () => {
  router.push({ path: "..." });
}
// highlight-end

onMounted(() => {
  // register the component
  // see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
  register(hankoApi)
    .catch((error) => {
      // handle error
    });
});
</script>

<template>
  // highlight-start
  <button @click="logout">Logout</button>
  <hanko-profile @onUserLoggedOut="redirectAfterLogout" />
  // highlight-end
</template>

```


## Customize component styles

The styles of the `hanko-auth` and `hanko-profile` can be customized using CSS variables and parts. See our guide
on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).

## Authenticate backend requests

If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).
